home *** CD-ROM | disk | FTP | other *** search
/ Freaks Macintosh Archive / Freaks Macintosh Archive.bin / Freaks Macintosh Archives / Cracking / Crack-It-Up.sit / Crack-It-Up / Crack-It-Up.rsrc / TEXT_136.txt < prev    next >
Text File  |  2000-01-29  |  17KB  |  474 lines

  1. Tips and Tricks for Macsbug
  2.  
  3. All of us who program on the Macintosh have lots of little tricks that we
  4. use to get our job done. Most of these are passed around via e-mail and the
  5. Usenet News, if they are passed on at all. In an effort to collect all these
  6. in one place for the benefit of all, I've created this page. Please submit
  7. your tips to crawford@scruznet.com and I will add them to this page - with
  8. proper attribution of course.
  9.  
  10. Contents
  11.  
  12. Where to get Macsbug
  13. Are there books that teach how to use Macsbug?
  14. Debugging Software on the Macintosh
  15. How to get Macsbug help for free
  16. Breaking While a Particular Application is Executing
  17. Logging Program Execution
  18. Logging Data in Real Time
  19. Using Cursors to Trace Program Execution
  20. Using Touch and Go Breakpoints with Two Monitors
  21. Twiddling Pixels in the Menu Bar
  22. Forcing Testers to Use Macsbug During Beta Testing
  23. The Developer University Debugging Class
  24. Links to Other Macsbug Pages
  25.  
  26. Where to get Macsbug
  27.  
  28.      Macsbug is available via anonymous FTP from Apple Computer from here or
  29.      here. It is included with the two books below, but you will want to get
  30.      the latest version, especially if you are using a PowerPC.
  31.  
  32. Are there books that teach how to use Macsbug?
  33.  
  34.      Yes, among them are:
  35.  
  36.         o Othmer and Strauss, Debugging Mac Software with Macsbug,
  37.           Addison-Wesley 1991, ISBN 0201570491. Macsbug included on disk.
  38.         o Apple Computer Inc., Macsbug Reference and Debugging Guide version
  39.           6.2, Addison-Wesley 1991, ISBN 0201567687. Macsbug 6.2 included on
  40.           disk.
  41.  
  42.      While you don't need to know how to write assembly code to use Macsbug
  43.      effectively, you will need to know how to read and understand it. Thus
  44.      you will also need to get assembly code reference manuals, such as:
  45.  
  46.         o Kacmarcik, Optimizing PowerPC Code, Addison-Wesley 1995, ISBN
  47.           0201408392.
  48.         o Motorola, M68000UM/AD MC68000 8/16/32-Bit MPU User Manual,
  49.           Motorola Literature Distribution, 1991.
  50.  
  51.      All of these books may be ordered from the Computer Literacy Bookstore.
  52.  
  53. How to get Macsbug help for free
  54.  
  55.      Contributed by Bill Coderre, bc@wetware.com
  56.  
  57.        1. Install Macsbug and programmer's key
  58.        2. Reboot the machine. Don't start any apps yet.
  59.        3. Hit CMD-POWER
  60.        4. type "log Macsbug Help <RETURN>"
  61.        5. type "help<RETURN>"
  62.        6. Push space until done.
  63.        7. type "log<RETURN>"
  64.        8. type "g<RETURN>"
  65.        9. Find the file called Macsbug Help on your desktop. Open it with a
  66.           text editor. Read it.
  67.  
  68. Breaking while a particular application is executing
  69.  
  70.      Most applications call WaitNextEvent. While an application is
  71.      executing, a Pascal string with the name of the application is placed
  72.      at location 0x910. Thus the first four characters of the name itself
  73.      begin at location 0x911. Suppose you want to break while SimpleText is
  74.      active. Enter Macsbug and give the command:
  75.  
  76.      atb WaitNextEvent 911^ = 'Simp'
  77.  
  78.      then continue. You will shortly drop into Macsbug at SimpleText's
  79.      WaitNextEvent call. This is particularly useful when debugging faceless
  80.      background applications. If the application does not call
  81.      WaitNextEvent, try GetNextEvent instead.
  82.  
  83. Logging Program Execution
  84.  
  85.      Contributed by Darren Giles, Terran Interactive, mars@netcom.com
  86.  
  87.      Always on the lookout for useful debugging tools & tips, I'd love to
  88.      share ideas with others on the topic. I'll start out by offering a
  89.      snippet I've found very useful -- hopefully others will do the same.
  90.  
  91.      One thing that's really bugged me about MacsBug on PPC is that the
  92.      stack crawl has become a much less useful tool. The snippet below gives
  93.      you the ability to keep track of a list of the last significant points
  94.      your program has visited. It's a list, not a stack, so you can also see
  95.      patterns of execution.
  96.  
  97.      Hardly rocket science, but useful & easy to add. Just call
  98.      DEBUG_STUFF_INIT at startup, then insert a DEBUG_ENTRY wherever you
  99.      want. To see what's up, especially during a bad hang, just dm [the
  100.      address that DEBUG_STUFF_INIT dumped out at startup.]
  101.  
  102.      The conditional compilation means that if you turn of debugging in your
  103.      final build, the release version of the program won't have any of this
  104.      code in it.
  105.  
  106.      [debugstuff.h]
  107.      #define DB_ROUTINES_NBR_ENTRIES 40
  108.      #define DB_ROUTINES_CHARS               16
  109.      typedef char                    db_routine_entry[DB_ROUTINES_CHARS];
  110.      #if DEBUGGING
  111.      void DEBUG_ENTRY (char *txt);
  112.      void DEBUG_STUFF_INIT (char *title);
  113.      #else
  114.      #define DEBUG_ENTRY
  115.      #define DEBUG_STUFF_INIT
  116.      #endif
  117.  
  118.      [debugstuff.c]
  119.      ///////////////////////////////////////////////////////////////////////
  120.      ////
  121.      #if DEBUGGING
  122.      void DEBUG_STUFF_INIT (char *title) {
  123.              OSErr                   myErr;
  124.              char                    txt[256];
  125.              long                    response;
  126.  
  127.  
  128.              if (!MacsBugInstalled()) {
  129.                      hi_notify ("MacsBug is not installed‚Ķ the debugging log will be
  130.      inaccessible.");
  131.              }
  132.  
  133.              g_debug_entries= (db_routine_entry*) NewPtrClear
  134.      ((DB_ROUTINES_NBR_ENTRIES+2) * DB_ROUTINES_CHARS);
  135.              memset (&g_debug_entries[0], '=', DB_ROUTINES_CHARS);
  136.              BlockMoveData (title, &g_debug_entries[0], strlen(title));
  137.              memset (&g_debug_entries[DB_ROUTINES_NBR_ENTRIES+1], '=',
  138.      DB_ROUTINES_CHARS);
  139.              sprintf (txt, "Debugging routine list is at 0x%lx;g", (long)
  140.      g_debug_entries);
  141.              c2pstr (txt);
  142.              DebugStr (txt);
  143.      }
  144.      #endif
  145.  
  146.      ///////////////////////////////////////////////////////////////////////
  147.      ////
  148.      //      This leaves a line in the debugging entry log.
  149.      //      For example, important enter/exit points of routines
  150.      ///////////////////////////////////////////////////////////////////////
  151.      ////
  152.      #if DEBUGGING
  153.      void DEBUG_ENTRY (char *txt) {
  154.              short                   len;
  155.  
  156.  
  157.              //      Move the previous entries down one
  158.              BlockMoveData (&g_debug_entries[1], &g_debug_entries[2],
  159.                              (DB_ROUTINES_NBR_ENTRIES-1) * DB_ROUTINES_CHARS);
  160.  
  161.              //      Clear the new space
  162.              memset (&g_debug_entries[1], 0, DB_ROUTINES_CHARS);
  163.  
  164.              //      Copy in the new entry
  165.              len= strlen (txt);
  166.              if (len > DB_ROUTINES_CHARS) {
  167.                      len= DB_ROUTINES_CHARS;
  168.              }
  169.              BlockMoveData (txt, &g_debug_entries[1], len);
  170.      }
  171.      #endif
  172.  
  173.      Hope this does someone some good.
  174.  
  175.      - Darren
  176.  
  177.      ==========================================================================
  178.      Darren Giles, Technical Director                        Terran Interactive
  179.      For info on Cleaner QuickTime compression, visit http://www.terran-int.com
  180.  
  181. Logging Data in Real Time
  182.  
  183.      Contributed by Dave Stone, dstone@chem.utoronto.ca
  184.  
  185.      I've also used conditional compilation to debug serial communications
  186.      stuff being processed at interrupt time - something like
  187.  
  188.      #ifdef DEBUG_MY_ROUTINE
  189.       #define MAX_BUFFER  10000
  190.              char bufffer[MAX_BUFFER];               //      or NewPtr it or something
  191.       long bufCount = 0L;
  192.      #endif
  193.      .
  194.      .
  195.      .
  196.      #ifdef DEBUG_MY_ROUTINE
  197.              if(bufCount <  MAX_BUFFER) {
  198.                      bufCount ++;
  199.              buffer[bufCount] = ch;                  //      ch is a character read/written through serial
  200.      port
  201.              }
  202.      #endif
  203.  
  204.      etc. Handy, because you can let it rip for a while to see if there is a
  205.      consistent pattern in the errors in ch - in my case, a stream of Midi
  206.      data through a very basic freeware Midi Driver.
  207.  
  208. Using Cursors to Trace Program Execution
  209.  
  210.      Contributed by Tom Kimpton, Jostens Learning Corporation, tom@jlc.com
  211.  
  212.      One technique that I have used in the past where dropping into the
  213.      debugger wasn't an option, and logging wasn't getting flushed in
  214.      time/took too long, was to create a bunch of cursors numbering 00 - 99,
  215.      and made a call to set the cursor and return the number of the previous
  216.      cursor:
  217.  
  218.      routine1()
  219.      {
  220.      short oldCursor = setDebugCursor(15);
  221.          ...
  222.          (void) setDebugCursor(oldCursor);
  223.      }
  224.  
  225.      This way when the machine froze, the cursor would tell me what routine
  226.      it had frozen in.
  227.  
  228. Using Touch and Go Breakpoints with Two Monitors
  229.  
  230.      I had a bug in which the Mac would occasionally freeze during shutdown
  231.      without the ability to get into Macsbug. It would only occur about once
  232.      in twenty reboots.
  233.  
  234.      The way I dealt with this was to borrow a display card and hook two
  235.      monitors up to the Macintosh. You can use the Monitors control panel to
  236.      select which monitor will be used for Macsbug (hold the option key and
  237.      drag the happy Mac around).
  238.  
  239.      I wrote a small application that just called ShutDownRestart(), and
  240.      placed it in the Startup Items folder. Thus, when the Mac came up into
  241.      the Finder it would immediately reboot. About every twenty minutes it
  242.      would freeze.
  243.  
  244.      If you define a macro named FirstTime in the Debugger Prefs file,
  245.      Macsbug will execute it when it loads. I used a macro that was
  246.      something like:
  247.  
  248.      swap; atr; atb shutdownrestart ";atb Newhandle ";g";g";g
  249.  
  250.      or some such. The swap command caused Macsbug to be permanently left on
  251.      the second screen. That way when the crash occurred you could still see
  252.      the last few things Macsbug did. The ";g" following the a-trap break
  253.      commands tells Macsbug to continue after the break - this is a "Touch
  254.      and Go" breakpoint.
  255.  
  256.      One thing you can also do inside a touch and go breakpoint is set new
  257.      breakpoints. I would take guesses on what traps might be called in the
  258.      neighborhood of the crash, and have breakpoints set on them when
  259.      ShutDownRestart was called.
  260.  
  261.      Then I could leave the Mac rebooting on its own in the lab, and pop in
  262.      every half an hour to check the log, adjust the breakpoints and start
  263.      it up again.
  264.  
  265.      The actual bug took about five months to find and fix.
  266.  
  267. Twiddling Pixels in the Menu Bar
  268.  
  269.      Contributed by Dave Fleck, Wacom Technology Corp., dfleck@wacom.com
  270.  
  271.      Here's my debugging tip.
  272.  
  273.      I do drivers, and you just plain can't set a breakpoint in ADB
  274.      completion routines (freezes the keyboard so MacsBug is worthless!).
  275.  
  276.      So I throw one of the routines below into the routine to see when a
  277.      piece of code gets executed.
  278.  
  279.      What does it do? It "lights up" a bar (length dependant on screen
  280.      resolution) in the menu bar. So if you DotToggle(300); you get a
  281.      flashing short line in the menu bar.
  282.  
  283.      void DotOn(long where) {
  284.         long  *dot;
  285.         dot = (long *)(LMGetScrnBase() + where);
  286.         *dot |= -1;
  287.      }
  288.      void DotOff(long where) {
  289.         long  *dot;
  290.         dot = (long *)(LMGetScrnBase() + where);
  291.         *dot &= 0;
  292.      }
  293.      void DotToggle(long where) {
  294.         long  *dot;
  295.         dot = (long *)(LMGetScrnBase() + where);
  296.         *dot ^= -1;
  297.      }
  298.  
  299.      dave
  300.  
  301.      -----------------------------------------------------------------
  302.      Dave Fleck   email:dfleck@wacom.com      phone:360-750-8882x154
  303.      Wacom Technology Corp.                          sales@wacom.com
  304.      501 S.E. Columbia Shores Blvd, #300           support@wacom.com
  305.      Vancouver, WA 98661                           WWW/FTP:wacom.com
  306.      ------------------------------------------------------------------
  307.  
  308. Forcing Testers to Use Macsbug During Beta Testing
  309.  
  310.      Contributed by Harold Ekstrom, the ag group, inc., ekstrom@aggroup.com.
  311.  
  312.      Don't you just hate it when beta testers say "it crashes" but don't
  313.      give you any more information? First, tell them to use the "stdlog"
  314.      command in MacsBug, then force them to install MacsBug by checking for
  315.      it during your program's initialization:
  316.  
  317.      --- DebugUtils.h ---
  318.  
  319.      #pragma once
  320.  
  321.      // Debugger types.
  322.      typedef enum DebuggerType {
  323.          kNoDebugger,
  324.          kMacsBug,
  325.          kTMON,
  326.          kOtherDebugger
  327.      } DebuggerType;
  328.  
  329.      Boolean     GetDebuggerInfo( DebuggerType *outDebuggerType,
  330.                      UInt16 *outDebuggerSignature );
  331.  
  332.      --- DebugUtils.c ---
  333.  
  334.      // Private defines for some low memory globals.
  335.      #define MacJmp      ((Ptr *)0x0120)     // MacsBug jumptable [pointer].
  336.      #define MacJmpByte  ((UInt8 *)0x0120)   // MacsBug flags in 24 bit mode [byte].
  337.      #define MacJmpFlag  ((UInt8 *)0x0BFF)   // MacsBug flag [byte].
  338.  
  339.      // Debugger flag bits.
  340.      #define kDebuggerInstalledBit   5
  341.  
  342.      //
  343.      ---------------------------------------------------------------------------------
  344.      //
  345.      //
  346.      ---------------------------------------------------------------------------------
  347.  
  348.      Boolean
  349.      GetDebuggerInfo(
  350.          DebuggerType *  outDebuggerType,
  351.          UInt16 *        outDebuggerSignature )
  352.      {
  353.          Boolean theResult = false;
  354.          SInt32  theResponse;
  355.  
  356.          // Initialize return values to defaults.
  357.          *outDebuggerType = kNoDebugger;
  358.          *outDebuggerSignature = '  ';
  359.  
  360.          if ( Gestalt( gestaltAddressingModeAttr, &theResponse ) == noErr ) {
  361.  
  362.              UInt16  theDebugFlags;
  363.  
  364.              // As documented in the "Macsbug Reference & Debugging Guide", page 412
  365.              // if we have a 32 bit capable Memory Manager, debugger flags are at 0x0BFF
  366.              // if we have a 24 bit capable Memory Manager, debugger flags are at 0x0120
  367.  
  368.              if ( (theResponse & (1L << gestalt32BitCapable)) != 0 ) {
  369.                  theDebugFlags = *MacJmpFlag;
  370.              } else {
  371.                  theDebugFlags = *MacJmpByte;
  372.              }
  373.  
  374.              if ( (theDebugFlags & (1L << kDebuggerInstalledBit)) != 0 ) {
  375.  
  376.                  Ptr theDebuggerEntry;
  377.                  Ptr theROMBaseWorld;
  378.  
  379.                  // There is a debugger installed.
  380.                  theResult = true;
  381.  
  382.                  // Get the debugger entry.
  383.                  theDebuggerEntry = StripAddress( *MacJmp );
  384.  
  385.                  // Get the ROM base.
  386.                  theROMBaseWorld = StripAddress( LMGetROMBase() );
  387.  
  388.                  // Compare the debugger entry to the ROM base.
  389.                  if ( theDebuggerEntry < theROMBaseWorld ) {
  390.  
  391.                      UInt16  **theDebuggerWorld;
  392.  
  393.                      // It's not a ROM based debugger.
  394.                      // Get the debugger world.
  395.                      theDebuggerWorld = (UInt16 **) StripAddress( theDebuggerEntry - sizeof(Ptr) );
  396.  
  397.                      // Get the debugger signature.
  398.                      *outDebuggerSignature = **theDebuggerWorld;
  399.  
  400.                      // Get the debugger type.
  401.                      switch ( *outDebuggerSignature ) {
  402.  
  403.                          case 'MT':
  404.                              *outDebuggerType = kMacsBug;
  405.                              break;
  406.  
  407.                          case 'WH':
  408.                              *outDebuggerType = kTMON;
  409.                              break;
  410.  
  411.                          default:
  412.                              *outDebuggerType = kOtherDebugger;
  413.                              break;
  414.  
  415.                      }
  416.  
  417.                  }
  418.  
  419.              }
  420.  
  421.          }
  422.  
  423.          return theResult;
  424.      }
  425.  
  426.      Check for a low level debugger like this:
  427.  
  428.      #if BETA_VERSION
  429.              DebuggerType    theDebuggerType;
  430.              UInt16          theDebuggerSig;
  431.              if ( !GetDebuggerInfo( &theDebuggerType, &theDebuggerSig ) ) {
  432.                  HaltRotateCursor( gRotateCrsr );
  433.                  StopAlert( go_get_macsbug_alrt, nil );
  434.                  ExitToShell();
  435.              }
  436.      #endif
  437.  
  438. The Developer University Debugging Class
  439.  
  440.      Contributed by Malcolm Teas, Blaze Technology, mhteas@btech.com
  441.  
  442.      As the instructor and developer of Apple's Developer University class
  443.      called "Macintosh Debugging Tips and Techniques" I would like to make
  444.      sure your tips page references this class.
  445.  
  446.      This class is centered around MacsBug as the easiest to learn low-level
  447.      debugger. It also covers a multitude of low-level topics like memory
  448.      maps, subroutine calling protocols, code segments and code fragments,
  449.      reading (and understanding) assembler for 68K and PPC, and many more
  450.      areas. One key area is how to avoid bugs in the first place. All the
  451.      information you need to be able to debug software at the low-level.
  452.  
  453.      The class is available from Apple's Developer University.
  454.  
  455.      Another thing I want to mention is the version number of the most
  456.      current MacsBug is 6.5.3 (as of this writing). This version includes
  457.      the PPC commands and features.
  458.  
  459.      [I have taken this class and recommend it highly - Mike]
  460.  
  461. Links to Other Macsbug Pages
  462.  
  463.         o Cool MacsBug Tricks (an informal guide)
  464.         o Macsbug Use
  465.         o Develop Issue 22: Balance of Power: MacsBug for PowerPC
  466.         o Macsbug 6.5.2 Help
  467.         o Macintosh Programming Books
  468.         o Guide to Mac Tools
  469.         o Macintosh Technical Q&A's
  470.         o comp.sys.mac.programming FAQ
  471.         o Macintosh Testing and Quality Control Tools
  472.         o Development and Debugging Tools for the Macintosh
  473.  
  474.